#include "Render/FixedPipelineShader.h"

#include "Core/VecMath.h"

#include <glut.h>
#include <glext.h>

static PFNGLBLENDCOLORPROC glBlendColor = NULL;

namespace vital {

	//--------------------------------------------------------------------------
	TFixedPipelineShader::TFixedPipelineShader(unsigned int GLTexId) {

		mGLTexId = GLTexId;
		mUseSmoothShading = true;
		mUseTexture = true;
		mUseAlphaBlend = false;
		mAlpha = 1.0f;

		if(!glBlendColor) {

			glBlendColor = (PFNGLBLENDCOLORPROC)wglGetProcAddress("glBlendColor");
		}
	}

	//--------------------------------------------------------------------------
	TFixedPipelineShader::~TFixedPipelineShader() {
	}

	//--------------------------------------------------------------------------
	size_t TFixedPipelineShader::beginRender() {
		return 1;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::beginPass(size_t passId) {

		if(passId > 0)
			return;

		glEnable(GL_DEPTH_TEST);

		glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, TVec4(0.0f, 0.0f, 0.0f, 1.0f).getData() );
		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, TVec4(1.0f, 1.0f, 1.0f, 1.0f).getData());
		glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, TVec4(1.0f, 1.0f, 1.0f, 1.0f).getData());
		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, TVec4(1.0f, 1.0f, 1.0f, 1.0f).getData());
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64.0f);

		glShadeModel( mUseSmoothShading ? GL_SMOOTH : GL_FLAT);

		glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0.0f);
		glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);

		glEnable(GL_LIGHTING);

		glCullFace(GL_BACK);
		glEnable(GL_CULL_FACE);

		if(mUseTexture) {

			glBindTexture(GL_TEXTURE_2D, mGLTexId);
			glEnable(GL_TEXTURE_2D);
		}
		else {

			glDisable(GL_TEXTURE_2D);
		}

		if(mUseAlphaBlend) {

			glEnable(GL_BLEND);
			glBlendFunc(GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA);

			if(glBlendColor)
				glBlendColor(1.0f, 1.0f, 1.0f, mAlpha);
		}
		else {

			glDisable(GL_BLEND);
		}
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::endPass() {

		glDisable(GL_BLEND);
		//glDisable(GL_LIGHTING);
		//glDisable(GL_DEPTH_TEST);
		//glDisable(GL_TEXTURE_2D);
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::endRender() {
	}

	//--------------------------------------------------------------------------
	bool TFixedPipelineShader::getUseSmoothShading() {

		return mUseSmoothShading;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::setUseSmoothShading(bool value) {

		mUseSmoothShading = value;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::toggleUseSmoothShading() {

		mUseSmoothShading = !mUseSmoothShading;
	}

	//--------------------------------------------------------------------------
	bool TFixedPipelineShader::getUseTexture() {

		return mUseTexture;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::setUseTexture(bool value) {

		mUseTexture = value;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::toggleUseTexture() {

		mUseTexture = !mUseTexture;
	}

	//--------------------------------------------------------------------------
	bool TFixedPipelineShader::getUseAlphaBlend() {

		return mUseAlphaBlend;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::setUseAlphaBlend(bool value) {

		mUseAlphaBlend = value;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::toggleUseAlphaBlend() {

		mUseAlphaBlend = !mUseAlphaBlend;
	}

	//--------------------------------------------------------------------------
	void TFixedPipelineShader::setAlpha(float value) {

		mAlpha = value;
	}

	//--------------------------------------------------------------------------
	float TFixedPipelineShader::getAlpha() {

		return mAlpha;
	}

	//--------------------------------------------------------------------------

}